﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace MadLibrary.Net.Ndmp
{
    /// <summary>
    /// Holds and manages response of NDMP protocol.
    /// </summary>
    public sealed class Response : IBuildable, IParsable
    {
        /// <summary>
        /// Gets or sets the request command.
        /// </summary>
        /// <value>
        /// The request command.
        /// </value>
        public NdmpCommand RequestCommand { get; set; }

        /// <summary>
        /// Gets or sets the data.
        /// </summary>
        /// <value>
        /// The data.
        /// </value>
        public string Data { get; set; }

        /// <summary>
        /// Gets or sets the status.
        /// </summary>
        /// <value>
        /// The status.
        /// </value>
        public NdmpStatus Status { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="Response"/> class.
        /// </summary>
        public Response()
        {
            this.RequestCommand = NdmpCommand.Unknown;
            this.Data = "";
            this.Status = NdmpStatus.Undone;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Response"/> class with specified data.
        /// </summary>
        /// <param name="Data">The data.</param>
        public Response(string Data)
        {
            this.RequestCommand = NdmpCommand.Select;
            this.Data = Data;
            this.Status = NdmpStatus.Done;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Response"/> class with all values for main properties of new Response.
        /// </summary>
        /// <param name="requestCommand">The request command.</param>
        /// <param name="data">The data.</param>
        /// <param name="status">The status.</param>
        public Response(NdmpCommand requestCommand, string data, NdmpStatus status)
        {
            this.RequestCommand = requestCommand;
            this.Data = data;
            this.Status = status;
        }

        /// <summary>
        /// Returns a <see cref="System.String"/> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            return String.Format("RESULT {0}\r\n{1}\r\n{2}\r\n", NCManager.ToString(this.RequestCommand), this.Data, NSManager.ToString(this.Status));
        }

        /// <summary>
        /// Builds object into string.
        /// </summary>
        /// <returns>
        /// Built string.
        /// </returns>
        string IBuildable.Build()
        {
            return this.ToString();
        }

        /// <summary>
        /// Parses string into current object.
        /// </summary>
        /// <param name="input">Specifies string which has to be parsed.</param>
        void IParsable.Parse(string input)
        {
            Match m = Regex.Match(input, "RESULT ([^\\r\\n]*)\\r\\n(.*)\\r\\n([^\\r\\n]*)\\r\\n", RegexOptions.Singleline);
            if(!m.Success)
                throw new Exception("Invalid input response passed for parsing.");
            else
            {
                this.RequestCommand = NCManager.ToCommand(m.Groups[1].Value);
                this.Data = m.Groups[2].Value;
                this.Status = NSManager.ToStatus(m.Groups[3].Value);
            }
        }
    }
}